<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * FormativeLab
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		FormativeLab
 * @author		FormativeLab Dev Team
 * @copyright	Copyright (c) 2011 - 2013, FormativeLab, Inc.
 * @license		http://www.formativesoft.com/license/
 * @link		http://www.formativesoft.com/
 * @since		Version 2.0
 * @filesource ./application/libraries/AbstractRenderer.php
 */

// ------------------------------------------------------------------------

/**
 * FormativeLab AbstractRenderer Library
 *
 * @package		FormativeLab
 * @subpackage	libraries
 * @category	libraries
 * @author		Formative Soft Ltd
 * @link		http://www.formativesoft.com/
 */

// ------------------------------------------------------------------------

/**
 * Renderer class use for render view in CodeIgniter MVC. This class used
 * to reduce boiler plate code of controllers. Renderer class use to auto
 * load view according to the controller and action name. This class was 
 * developed by the inspiration of groovy on grails. To Autoload views and
 * respectives layout.
 **/
abstract class AbstractRenderer{
	
	/**
	 * CodeIgniter Instance property. loaded during the initialization 
	 * of class. This intance is required to load others properties.
	 **/
	protected $controller;
	
	/**
	 * CodeIgniter helpers and library. these are loaded during the 
	 * initialization of class.
	 **/
	protected $input;
	protected $output;
	protected $session;
	
	/**
	 * CodeIgniter view layout in where view content will be injected to render
	 * complete response.
	 **/
	private $layout;
	
	/**
	 * This private property use to store controller name and action name. These
	 * properties are helpful to resolve view automatically.
	 **/
	private $moduleName;
	private $controllerName;
	private $actionName;
		
	/**
	 * CodeIgniter runtime required helpers and library to load automatically
	 * during the initialization of class.
	 **/
	static $helper 		= array('security', 'url', 'method', 'resource');
	static $library		= array('session');
		
	/**
	 * Constraints declaration for codeIgniter view layouts and fragments
	 * for reusable templeting and reducing boiler plate of code
	 **/
	const DIR_MODULES			= 'modules';
	const DIR_FRAGMEENTS		= 'fragments';
	const DIR_LAYOUTS			= 'layouts';
	
	const DIR_BANNERS			= 'banners';
	const DIR_ELEMENTS			= 'elements';
	const DIR_FOOTERS			= 'footers';
	const DIR_MENUS				= 'menus';
	const DIR_SIDEBAR			= 'sidebars';	
	
	/**
	 * __construct() used to initialized intance objects, properties and 
	 * configuration. It's also load required library and helpers
	 *
	 * @access	public
	 * @param	layout
	 * @return  void 
	 **/
    public function __construct($layout	= 'defaults'){		
        $this->controller 	= &get_instance();	
		$this->controller->load->helper(self::$helper);
        $this->controller->load->library(self::$library);
		
		$this->input  		= &$this->controller->input;
		$this->output 		= &$this->controller->output;
		$this->session 		= &$this->controller->session;		
		$this->layout		= empty($layout) ? 'defaults' : $layout;
    }
	
	/**
	 * getModuleName() without any parameters use to get current Module name for
	 * current request.
	 *
	 * @access	public
	 * @return  string 
	 **/
	public function getModuleName(){
		return $this->moduleName;
	}
	
	/**
	 * getControllerName() without any parameters use to get current Controller name for
	 * current request.
	 *
	 * @access	public
	 * @return  string 
	 **/
	public function getControllerName(){
		return $this->controllerName;
	}
	
	/**
	 * getActionName() without any parameters use to get current Action name for
	 * current request.
	 *
	 * @access	public
	 * @return  string 
	 **/
	public function getActionName(){
		return $this->actionName;
	}
	
	/**
	 * setLayout() with an required parameter use to set layout to render view
	 * in deffernet layout.
	 *
	 * @access	public
	 * @param	layout
	 * @return  void 
	 **/
	public function setLayout($layout){
		$this->layout	= $layout;
	}
	
	
	/**
	 * response() with two parameter use to load view dynamically. Both parameters
	 * are optional. this method is use to response view dynamically as it layout
	 * and others fragments.
	 *
	 * @access	public
	 * @param	data
	 * @param 	viewPath
	 * @return  void 
	 **/
	public abstract function response(Array $data = array(), $viewPath = NULL);
	
	/**
	 * jsonData() with two parameter use to response Array to json dynamically. Both 
	 * parameters are optional. This method use for Extjs 4.1 Data package.
	 *
	 * @access	public
	 * @param   data
	 * @param   status
	 * @return	void
	 */
	public function jsonData(Array $data = array(), $status = 200){
		jsonDataRender($data, $status);
	}
		
	/**
	 * jsonMessage()  with three parameter use to response String to json dynamically. all 
	 * parameters are optional. This method use for Extjs 4.1 Data package.
	 *
	 * @access	public
	 * @param   message
	 * @param   success
	 * @param   status
	 * @return	void
	 **/
	public function jsonMessage($message = '', $success = true, $status = 200){
		jsonRender($message, $success, $status);
	}
	
	/**
	 * simpleXML() with three parameter use to response Array to XML dynamically. First
	 * parameter is required and rest of parameters are optinal. 
	 *
	 * @access	public
	 * @param   data
	 * @param	format
	 * @param   status
	 * @return	void
	 */
	public function simpleXML($data, $format = true, $status = 200){
		renderSimpleXMLElementAsXML($data, $format, $status);
	}
	
	/**
	 * standardXML() with four parameter use to response Array to XML dynamically. First
	 * parameter is required and rest of parameters are optinal. 
	 *
	 * @access	public
	 * @param   data
	 * @param	rootElement
	 * @param	format
	 * @param   status
	 * @return	void
	 */
	public function standardXML($data, $rootElement = 'root', $format = true, $status = 200){
		renderDataAsXML($data, $rootElement, $format, $status);
	}
	
	/**
	 * loadBanner() with two parameters use to load banner view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	banner
	 * @param	data
	 * @return  string 
	 **/
	protected function loadBanner($banner, Array $data = array()){
		$fragment	= sprintf("%s/%s", self::DIR_BANNERS, $banner);
		return $this->loadFragment($fragment, $data);
	}
	
	/**
	 * loadElement() with two parameters use to load element view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	element
	 * @param	data
	 * @return  string 
	 **/
	protected function loadElement($element, Array $data = array()){
		$fragment	= sprintf("%s/%s", self::DIR_ELEMENTS, $element);
		return $this->loadFragment($fragment, $data);
	}
		
	/**
	 * loadFooter() with two parameters use to load footer view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	footer
	 * @param	data
	 * @return  string 
	 **/
	protected function loadFooter($footer, Array $data = array()){
		$fragment	= sprintf("%s/%s", self::DIR_FOOTERS, $footer);
		return $this->loadFragment($fragment, $data);
	}
	
	/**
	 * loadMenu() with two parameters use to load menu view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	menu
	 * @param	data
	 * @return  string 
	 **/
	protected function loadMenu($menu, Array $data = array()){
		$fragment	= sprintf("%s/%s", self::DIR_MENUS, $menu);
		return $this->loadFragment($fragment, $data);
	}
	
	/**
	 * loadSidebar() with two parameters use to load sidebar view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	sidebar
	 * @param	data
	 * @return  string 
	 **/
	protected function loadSidebar($sidebar, Array $data = array()){
		$fragment	= sprintf("%s/%s", self::DIR_SIDEBAR, $sidebar);
		return $this->loadFragment($fragment, $data);
	}
	
	/**
	 * loadFragment() with two parameters use to load fragment view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	fragment
	 * @param	data
	 * @return  string 
	 **/
	protected function loadFragment($fragment, Array $data = array()){
		$controller		= &$this->controller;
		$fragmentPath	= sprintf("%s/%s", self::DIR_FRAGMEENTS, $fragment);
		$contents		= $controller->load->view($fragmentPath, $data, true);
		return $contents;
	}
	
	/**
	 * loadView() with three parameter use to load view dynamically. First one
	 * is required parameter and rest of two are optional.
	 *
	 * @access	protected
	 * @param 	viewPath
	 * @param	data
	 * @param	echo
	 * @return  string 
	 **/
	protected function loadView($viewPath, Array $data = array()){
		$controller			= &$this->controller;
		$resolvedViewPath 	= $this->resolveViewPath($viewPath);
		$contents			= $controller->load->view($resolvedViewPath, $data, true);
		return $contents;
	}
		
	/**
	 * loadLayout() with two parameters use to load Layout view dynamically. First
	 * one is required parameter and rest of one is optional.
	 *
	 * @access	protected
	 * @param 	layout
	 * @param	data
	 * @return  void 
	 **/
	protected function loadLayout(Array $data = array()){
		$controller		= &$this->controller;
		$layoutPath		= $this->resolveLayoutPath();
		$controller->load->view($layoutPath, $data);
	}
	
	/**
	 * resolveViewPath() with an optional parameter use to resolve view path from 
	 * router.
	 *
	 * @access	private
	 * @param 	view
	 * @return  string 
	 **/
	private function resolveViewPath($view = NULL){
		$controller		= strtolower($this->controllerName);
		$action 		= strtolower($this->actionName);
		
		if(!$this->isModullar()){
			$resolvedPath	= sprintf("%s/%s", $controller, $action);
		}else{
			$resolvedPath	= sprintf("%s/%s/%s", $this->moduleName, $controller, $action);
		}
		return $view ? $view : $resolvedPath;		
	}
	
	/**
	 * resolveLayoutPath() without any parameter use to resolve layout view path from 
	 * router.
	 *
	 * @access	private
	 * @return  string 
	 **/
	private function resolveLayoutPath(){
		$layout			= $this->resolveLayoutName();
		if(!$this->isModullar()){
			$resolvedPath	= sprintf("%s/%s", self::DIR_LAYOUTS, $layout);
		}else{
			$resolvedPath	= sprintf("%s/%s/%s", $this->moduleName, self::DIR_LAYOUTS, $layout);
		}
		return $resolvedPath;		
	}
	
	/**
	 * resolveLayoutName() with an required parameter use to resolve layout name if 
	 * layout file not exists its return the default layout name.
	 *
	 * @access	protected
	 * @return  string 
	 **/
	protected function resolveLayoutName(){
		$layout	= strtolower($this->controllerName);
		return $this->isLayoutExists() ? $layout : $this->layout;
	}
	
	/**
	 * isLayoutExists() with an required parameter use to check whether layout file
	 * exists or not. This method helpful to load layout dynamically if the layout is
	 * exists.
	 *
	 * @access	private
	 * @param	layout
	 * @return  bool 
	 **/
	private function isLayoutExists(){
		$layout				= strtolower($this->controllerName);
		$viewsBasePath		= $this->resolveViewsBasePath();
		$layoutAbsolutePath = sprintf( "%s/%s/%s.php", $viewsBasePath, self::DIR_LAYOUTS, $layout);
		return @file_exists($layoutAbsolutePath);
	}
	
	/**
	 * resolveControllerAction() without any parameter use to resolve module, controller and 
	 * action name from router.
	 *
	 * @access	protected
	 * @return  void 
	 **/
	protected function resolveModuleControllerAction(){
		$controller				= &$this->controller;
		$this->moduleName		= $controller->router->fetch_module();
		$this->controllerName	= $controller->router->fetch_class();
		$this->actionName 		= $controller->router->fetch_method();
	}
	
	/**
	 * resolveModuleBasePath() without any parameter use to resolve moudule base from request
	 * for each controller action whether it's modullar or not.
	 *
	 * @access	private
	 * @return  void 
	 **/
	private function resolveViewsBasePath(){
		if(!$this->isModullar()){
			$viewsBasePath = sprintf( "%sviews/", APPPATH);
		}else{
			$viewsBasePath = sprintf( "%smodules/%s/views", APPPATH, self::DIR_MODULES);
		}
		return $viewsBasePath;
	}
	
	/**
	 * isModullar() without any parameter use to check whether the request from an modullar
	 * controller or not.
	 *
	 * @access	public
	 * @return  void 
	 **/
	public function isModullar(){
		$moduleName		= $this->moduleName;
		return !is_null($moduleName) && !empty($moduleName);
	}
  
	/**
	 * encrypt() used to crypt/Crytography for digesting password and ensuring
	 * security of this application
	 *
	 * @access	public
	 * @return  string 
	 **/
    protected function encrypt($password){
		return do_hash($password);
    }
	
}

/* End of file AbstractRenderer.php */
/* Location: ./application/libraries/AbstractRenderer.php */